/*

定义模板类Mat，实现以下要求：

2. Mat应当是静态分配，也不能含有虚函数。
  - sizeof(Mat<R,C,T>)应为 R * C * sizeof(T)
3. 添加能够接受数组和长度的构造函数：`Mat(const T v[], int n)`
  - 初始值的数量（数组长度）可以小于矩阵元素数，无初值的元素默认初始化。
4. 重载下标操作符
  - `T* operator[](int r);`
  - `const T* operator[](int r) const;`
*/

// 定义开始
// todo
// 定义结束

/**
 * TODO: 需求1. 静态矩阵类的定义。你的类实现应当是下方包含的文件名。
 * @attention 模板类编译（实例化）时必须能看到类及其成员函数的定义。
 * 因此传统上模板类的实现部分也写在头文件中，而不是CPP文件。
 */
#include "static_mat.hpp"

/**
 * TODO: 需求2. 测试对重复包含的处理。
 * @attention 头文件被重复包含是常见、甚至难以避免的情况。
 * 由于模板类的定义在头文件中，重复包含会导致类或变量重复定义。
 * 因此头文件需要用“保护宏”或pragma once指令预防重复包含导致的重定义。
 */
#include "static_mat.hpp"

#include <cassert>
#include <iostream>
using namespace std;

int main() {
  {
    /**
     * TODO: 需求3. Mat有三个模板参数R、C、T.
     * @attention R是行数、C是列数，都是整型，属于“非类型参数”，描述矩阵的尺寸。
     * T是模板的类型参数。
     * @warning 了解“静态断言static_assert”的功能，能否用assert()代替？
     * @warning R、C参数能否用变量？
     */
    static_assert(sizeof(Mat<1, 1, char>) == 1);
    static_assert(sizeof(Mat<4, 3, short>) == 24); // 4 * 3 * 2
    static_assert(sizeof(Mat<2, 3, float>) == 24); // 2 * 3 * 4
  }
  {
    /**
     * TODO: 需求4. Mat<R,C,T>的类型参数T默认为double型。
     * @brief 有了默认类型参数，使用时可以简写。
     */
    Mat<2, 3> m23;  // 这里省略了T对应的类型，默认为double。
    assert(sizeof(m23) == 2 * 3 * sizeof(double));
  }
}